package com.yss.sofa.report.engine.cell.invisible.dataset;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yss.sofa.report.engine.Const;
import com.yss.sofa.report.engine.Context;
import com.yss.sofa.report.engine.DataSet;
import com.yss.sofa.report.engine.DataSetData;
import com.yss.sofa.report.engine.cell.ReportCell;
import com.yss.sofa.report.engine.cell.invisible.InvisibleCell;
import com.yss.sofa.report.engine.util.ScriptUtil;


public class ScriptDataSetCell extends InvisibleCell implements DataSet{
	private static final long serialVersionUID = 8462348678453016357L;
	private static final Logger LOGGER=LoggerFactory.getLogger(ScriptDataSetCell.class);
	private String script;
	private String exec;
	private Set<String> params=new HashSet<String>();
	protected void init() {
		super.init();
		this.type=Const.REPORT_CELL_TYPE_SCRIPT_DATASET;
		this.exec="true";
	}
	public void assignTo(ReportCell cell){
		ScriptDataSetCell _=(ScriptDataSetCell)cell;
		super.assignTo(_);
		_.script=this.script;
		_.exec=this.exec;
		_.params.clear();
		_.params.addAll(this.params);
	}
	public ScriptDataSetCell create(){
		ScriptDataSetCell _=new ScriptDataSetCell();
		this.assignTo(_);
		return _;
	}
	public String getScript() {
		return script;
	}
	public void setScript(String script) {
		this.script = script;
	}
	public Set<String> getParams() {
		return params;
	}
	public void setParams(Set<String> params) {
		this.params = params;
	}
	public DataSetData execute(String classname,Context context,Map<String,Serializable> paramsmap,Map<String,String> consts) throws Exception {
		Map<String,Object> vars=new HashMap<String, Object>();
		Map<String,Serializable> values=new HashMap<String, Serializable>();
		for(String key:params){
			values.put(key, paramsmap.get(key));
		}
		vars.put("CONSTS", consts);
		vars.put("params", values);
		context.remove(Context.CONTEXT_KEY_DATASET_DATAS);
		vars.put("context", context);
		vars.put("db", new ScriptUtil.Db(context));
		vars.put("auth", new ScriptUtil.Auth(paramsmap.containsKey(Const.SYS_PARAMS_USER_ID)?paramsmap.get(Const.SYS_PARAMS_USER_ID).toString():null));
		vars.put("util", new ScriptUtil.Util(values));
		vars.put("cache", new ScriptUtil.Cache((String)paramsmap.get(Const.SYS_PARAMS_REPORT_CODE)));
		DataSetData data;
		try {
			data = ScriptUtil.execute(classname, script, vars, DataSetData.class,true);
			if((data==null) && !context.containsKey(Context.CONTEXT_KEY_DATASET_DATAS)){
				throw new Exception("Script数据集["+code+"]的返回结果为null");
			}
			if(context.containsKey(Context.CONTEXT_KEY_DATASET_DATAS)){
				Object map=context.get(Context.CONTEXT_KEY_DATASET_DATAS);
				if(map==null){
					throw new Exception("Script数据集["+code+"]通过context返回的数据为null");
				} else {
					if(!(map instanceof Map)){
						throw new Exception("Script数据集["+code+"]通过context返回的数据不合法");
					} else {
						@SuppressWarnings("unchecked")
						Map<String,DataSetData> datas=(Map<String,DataSetData>)map;
						if(datas.isEmpty()){
							throw new Exception("Script数据集["+code+"]通过context返回的数据为空");
						} else {
							Set<String> keys=datas.keySet();
							for(String key:keys){
								DataSetData _=datas.get(key);
								if(_==null){
									throw new Exception("Script数据集["+code+"]通过context返回的数据["+key+"]为null");
								} else if(_.convert().size()>10000){
									LOGGER.warn("Script数据集["+code+"]通过context返回的数据["+key+"]已超过10000条");
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			throw new Exception("Script数据集["+code+"]执行失败",e);
		}
		if(data!=null && data.convert().size()>10000){
			LOGGER.warn("Script数据集["+code+"]返回的数据已超过10000条");
		}
		return data;
	}
	public String getExec() {
		return exec;
	}
	public void setExec(String exec) {
		this.exec = exec;
	}
}
